home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Simulation / PDP-8 Simulator / Source Code / PDPUtilities.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-13  |  13.6 KB  |  676 lines  |  [TEXT/KAHL]

  1. /*************************************************************************************
  2. *
  3. *        PDP-8 Simulation Program- utilities, dialogs and initialisation
  4. *
  5. *        ©1992 Graham Cox. All Rights Reserved.
  6. *
  7. *        Modification History:
  8. *        3/3/92 created from scratch.    
  9. *
  10. *
  11. *
  12. *************************************************************************************/
  13.  
  14. #include    "PDPGlobalEqu.p"
  15.  
  16. #include "PDPUtilities.proto.h"
  17.  
  18. int        ProcessIndex = 1;
  19.  
  20.  
  21. PDPRegHdl    NewProcessor(void)
  22. {
  23.     /* allocates storage for a new processor data structure, initialises its fields
  24.         and returns a handle to it */
  25.         
  26.     PDPRegHdl    temp;
  27.     
  28.     temp = (PDPRegHdl) NewHandle(sizeof(PDPRegisters));
  29.     if (temp != NIL) {
  30.         (*temp)->PC = 0;
  31.         (*temp)->ACC = 0;
  32.         (*temp)->CCR = 0x80;
  33.         (*temp)->EAR = 0;
  34.         SetRect(&(*temp)->markerLoc,0,0,0,0);
  35.     }
  36.     return(temp);
  37. }
  38.  
  39.  
  40. ResetProcessor(PDPRegHdl theCPU)
  41. {
  42.     /* resets the CPU so that the PC contains zero. No other registers affected */
  43.     
  44.     if (theCPU != NIL)
  45.         (*theCPU)->PC = 0;
  46. }
  47.  
  48.  
  49. HaltProcessor(PDPRegHdl theCPU)
  50. {
  51.     /* sets the halt bit in the CCR. No other registers affected */
  52.     
  53.     if (theCPU != NIL)
  54.         (*theCPU)->CCR |= HaltBit;
  55. }
  56.  
  57.  
  58. StartProcessor(PDPRegHdl theCPU)
  59. {
  60.     /* clears the halt bit in the CCR. Nothing else affected */
  61.     
  62.     if (theCPU != NIL)
  63.         (*theCPU)->CCR &= (0xFF - HaltBit);
  64. }
  65.  
  66.  
  67. PDPMemHdl    NewPDPMemory(void)
  68. {
  69.     /* returns a handle to a new block of simulated memory. This block will contain
  70.         random data */
  71.         
  72.     return((PDPMemHdl) NewHandle(sizeof(PDPMemory)));
  73. }
  74.  
  75.  
  76. InitProcessWindow(WindowPtr theWindow)
  77. {
  78.     /* given a window, this procedure creates space for a cpu, a memory record, and a
  79.         process record, and sets the windows refcon field to contain its handle. The
  80.         windowKind field is set to SimulatorKind. This associates the window with a 
  81.         process which is so much better than defining globals. */
  82.         
  83.     ProcessRecHdl    theProcess;
  84.     PDPMemHdl        theMem;
  85.     PDPRegHdl        theCPU;
  86.     PrefsRecHdl        thePrefs;
  87.     ControlHandle    mScroll;
  88.     Rect            sBarRect;
  89.     Str32            procName,wTit;
  90.     GrafPtr            savePort;
  91.     
  92.     if (theWindow != NIL) {
  93.         theProcess = (ProcessRecHdl) NewHandle(sizeof(ProcessRec));
  94.         if (theProcess != NIL) {
  95.             theMem = NewPDPMemory();
  96.             theCPU = NewProcessor();
  97.             (*theProcess)->theMemory = theMem;
  98.             (*theProcess)->theCPU = theCPU;
  99.             (*theProcess)->processOwner = theWindow;
  100.             thePrefs = (PrefsRecHdl)NewHandle(sizeof(PrefsRec));
  101.             SetPrefDefaults(thePrefs);
  102.             (*theProcess)->procPrefs = thePrefs;
  103.             (*theProcess)->reserved2 = NIL;
  104.             (*(WindowPeek)theWindow).windowKind = SimulatorKind;
  105.             
  106.             sBarRect = theWindow->portRect;
  107.             sBarRect.left = sBarRect.right-15;
  108.             sBarRect.right +=1;
  109.             sBarRect.bottom -= 14;
  110.             sBarRect.top--;
  111.             
  112.             mScroll = NewControl(theWindow,&sBarRect,"\p",TRUE,0,0,4095,16,NIL);
  113.             (*theProcess)->memScroll = mScroll;
  114.             (*theProcess)->memLocHeight = 20;
  115.             
  116.             NumToString(ProcessIndex,&procName);
  117.             CopyString("\pPDP-8 Process ",&wTit);
  118.             ConcatString(&wTit,&procName);
  119.             SetWTitle(theWindow,&wTit);
  120.             
  121.             (*theProcess)->processID = ProcessIndex;
  122.             ProcessIndex += 1;
  123.             
  124.             GetPort(&savePort);
  125.             SetPort(theWindow);
  126.             TextFont(0);
  127.             TextSize(12);
  128.             SetPort(savePort);
  129.             
  130.         }
  131.         SetWRefCon(theWindow,(long)theProcess);
  132.         ClearProcessMem(theWindow);
  133.     }
  134. }
  135.  
  136.  
  137. int    IsSimulator(WindowPtr theWindow)
  138. {
  139.     /* returns true if windowkind is SimulatorKind, else false */
  140.     
  141.     return((theWindow != NIL) && ((*(WindowPeek)theWindow).windowKind == SimulatorKind));
  142. }
  143.  
  144.  
  145. ProcessRecHdl    GetProcess(WindowPtr theWindow)
  146. {
  147.     /* returns handle to process if window is simulator kind */
  148.     
  149.     if (IsSimulator(theWindow))
  150.         return((ProcessRecHdl)GetWRefCon(theWindow));
  151.     else
  152.         return(NIL);
  153. }
  154.  
  155.  
  156. int GetProcessID(WindowPtr theWindow)
  157. {
  158.     /* returns the ID number of the associated process */
  159.     
  160.     ProcessRecHdl    theProc;
  161.     
  162.     theProc = GetProcess(theWindow);
  163.     if (theProc != NIL)
  164.         return((*theProc)->processID);
  165.     else
  166.         return(0);
  167. }
  168.  
  169.  
  170. PDPRegHdl    GetCPU(WindowPtr theWindow)
  171. {
  172.     /* returns associated CPU handle from window */
  173.     
  174.     ProcessRecHdl    theProcess;
  175.     
  176.     theProcess = GetProcess(theWindow);
  177.     if (theProcess != NIL)
  178.         return((*theProcess)->theCPU);
  179.     else
  180.         return(NIL);
  181. }
  182.  
  183.  
  184. PDPMemHdl    GetMemory(WindowPtr theWindow)
  185. {
  186.     /* returns associated memory handle from window */
  187.     
  188.     ProcessRecHdl    theProcess;
  189.     
  190.     theProcess = GetProcess(theWindow);
  191.     if (theProcess != NIL)
  192.         return((*theProcess)->theMemory);
  193.     else
  194.         return(NIL);
  195. }
  196.  
  197.  
  198. ControlHandle    GetMemScrollbar(WindowPtr theWindow)
  199. {
  200.     /* returns associated scrollbar handle from window */
  201.     
  202.     ProcessRecHdl    theProcess;
  203.     
  204.     theProcess = GetProcess(theWindow);
  205.     if (theProcess != NIL)
  206.         return((*theProcess)->memScroll);
  207.     else
  208.         return(NIL);
  209. }
  210.  
  211.  
  212. PrefsRecHdl    GetPrefs(WindowPtr theWindow)
  213. {
  214.     /* returns associated preferences handle from window */
  215.     
  216.     ProcessRecHdl    theProcess;
  217.     
  218.     theProcess = GetProcess(theWindow);
  219.     if (theProcess != NIL)
  220.         return((*theProcess)->procPrefs);
  221.     else
  222.         return(NIL);
  223. }
  224.  
  225.  
  226. NumToHexx(long theNum,Str255 *theString)
  227. {
  228.     /* converts a number to Hexadecimal string */
  229.     
  230.     int        sLength;
  231.     unsigned long    i,r;
  232.     Ptr        temp,s2;
  233.     char    revStr[32];
  234.     
  235.     sLength = 0;
  236.     i = theNum;
  237.     temp = &revStr[0];
  238.     
  239.     if (i==0)
  240.         CopyString("\p0",theString);
  241.     else {
  242.         while (i>0) {
  243.             r = i % 16;
  244.             i /= 16;
  245.             if (r>9)
  246.                 *temp = (r & 0xFF) + 0x37;
  247.             else
  248.                 *temp = (r & 0xFF) + 0x30;
  249.                 
  250.             temp++;
  251.             sLength++;
  252.         }
  253.         *theString[0] = sLength;
  254.         s2 = (Ptr)theString;
  255.         s2++;
  256.         
  257.         while(sLength >0) {
  258.             temp--;
  259.             *s2 = *temp;
  260.             s2++;
  261.             sLength--;
  262.         }
  263.     }
  264. }
  265.  
  266.  
  267. NumToOctal(long theNum,Str255 *theString)
  268. {
  269.     /* converts a number to Octal string */
  270.     
  271.     int        sLength;
  272.     unsigned long    i,r;
  273.     Ptr        temp,s2;
  274.     char    revStr[32];
  275.     
  276.     sLength = 0;
  277.     i = theNum;
  278.     temp = &revStr[0];
  279.     
  280.     if (i==0)
  281.         CopyString("\p0",theString);
  282.     else {
  283.         while (i>0) {
  284.             r = i % 8;
  285.             i /= 8;
  286.             
  287.             *temp = (r & 0xFF) + 0x30;
  288.                 
  289.             temp++;
  290.             sLength++;
  291.         }
  292.         *theString[0] = sLength;
  293.         s2 = (Ptr)theString + 1;
  294.         
  295.         while(sLength >0) {
  296.             temp--;
  297.             *s2 = *temp;
  298.             s2++;
  299.             sLength--;
  300.         }
  301.     }
  302. }
  303.  
  304.  
  305. HexStringToNum(Str32 *theString,unsigned long *theNum)
  306. {
  307.     /* converts a hexadecimal string to a number */
  308.     
  309.     int                count,sLength;
  310.     unsigned long    rTotal,weight;
  311.     Ptr                sPtr;
  312.     char            ascii;
  313.     
  314.     rTotal = 0;
  315.     sPtr = theString;
  316.     sLength = *sPtr;
  317.     sPtr += sLength;
  318.     weight = 1;
  319.     
  320.     for (count = 0;count < sLength;count++) {
  321.         ascii = *sPtr;
  322.         if (ascii > 0x40)
  323.             rTotal += (ascii - 0x37) * weight;
  324.         else
  325.             rTotal += (ascii - 0x30) * weight;
  326.             
  327.         sPtr--;
  328.         weight *= 16;
  329.     }
  330.     *theNum = rTotal;
  331. }
  332.  
  333.  
  334. OctStringToNum(Str32 *theString,unsigned long *theNum)
  335. {
  336.     /* converts an octal string to a number */
  337.     
  338.     int                count,sLength;
  339.     unsigned long    rTotal,weight;
  340.     Ptr                sPtr;
  341.     char            ascii;
  342.     
  343.     rTotal = 0;
  344.     sPtr = theString;
  345.     sLength = *sPtr;
  346.     sPtr += sLength;
  347.     weight = 1;
  348.     
  349.     for (count = 0;count < sLength;count++) {
  350.         ascii = *sPtr;
  351.         rTotal += (ascii - 0x30) * weight;
  352.             
  353.         sPtr--;
  354.         weight *= 8;
  355.     }
  356.     *theNum = rTotal;
  357. }
  358.  
  359.  
  360. #define    PrefDialogID        512
  361. #define    PDFastButton        3
  362. #define    PDMediumButton        4
  363. #define PDSlowButton        5
  364.  
  365. #define PDVectorEditField    8
  366. #define PDDecimalButton        10
  367. #define PDOctalButton        11
  368. #define    PDHexButton            12
  369. #define    PDBinaryButton        13
  370. #define    PDGroupFrame1        14
  371. #define PDGroupFrame2        15
  372. #define    PDShowEARButton        16
  373. #define    PDShowMnemonics        17
  374. #define    PDTrackPCButton        18
  375.  
  376. pascal void FrameRectUserItem(DialogPtr theDialog,int theItem)
  377. {
  378.     /* user item proc to draw frames in dialog boxes */
  379.     
  380.     int        itemType;
  381.     Handle    itemHand;
  382.     Rect    itemBox;
  383.     
  384.     GetDItem(theDialog,theItem,&itemType,&itemHand,&itemBox);
  385.     FrameRect(&itemBox);
  386. }
  387.  
  388.  
  389. PDPPreferences(PrefsRecHdl thePrefs)
  390. {
  391.     /* sets up preferences data structure using dialog box */
  392.     
  393.     DialogPtr    theDialog;
  394.     int            theItem,itemType,i;
  395.     Handle        itemHand;
  396.     Rect        itemBox;
  397.     
  398.     theDialog = GetNewDialog(PrefDialogID,NIL,(WindowPtr)-1L);
  399.  
  400.     if (theDialog != NIL) {
  401.         
  402.         SetUserItem(theDialog,PDGroupFrame1,&FrameRectUserItem);
  403.         SetUserItem(theDialog,PDGroupFrame2,&FrameRectUserItem);
  404.         PosDialog(theDialog);
  405.         OutlineDItem(theDialog,1);
  406.         
  407.         SetPrefButtons(theDialog,thePrefs);
  408.         SelIText(theDialog,PDVectorEditField,0,32767);
  409.         
  410.         theItem = 0;
  411.         
  412.         while (theItem == 0) {
  413.             ModalDialog(NIL,&theItem);
  414.             
  415.             switch (theItem) {
  416.                 case ok:
  417.                     GetPrefButtons(theDialog,thePrefs);
  418.                 case cancel:
  419.                     break;
  420.                 case PDFastButton:
  421.                 case PDMediumButton:
  422.                 case PDSlowButton:
  423.                     for (i=PDFastButton;i<=PDSlowButton;i++) {
  424.                         GetDItem(theDialog,i,&itemType,&itemHand,&itemBox);
  425.                         if (i==theItem)
  426.                             SetCtlValue(itemHand,1);
  427.                         else
  428.                             SetCtlValue(itemHand,0);
  429.                     }
  430.                     theItem = 0;
  431.                     break;
  432.                 case PDDecimalButton:
  433.                 case PDOctalButton:
  434.                 case PDHexButton:
  435.                 case PDBinaryButton:
  436.                     for (i=PDDecimalButton;i<=PDBinaryButton;i++) {
  437.                         GetDItem(theDialog,i,&itemType,&itemHand,&itemBox);
  438.                         if (i==theItem)
  439.                             SetCtlValue(itemHand,1);
  440.                         else
  441.                             SetCtlValue(itemHand,0);
  442.                     }
  443.                     theItem = 0;
  444.                     break;
  445.                 case PDShowEARButton:
  446.                 case PDShowMnemonics:
  447.                 case PDTrackPCButton:
  448.                     GetDItem(theDialog,theItem,&itemType,&itemHand,&itemBox);
  449.                     SetCtlValue(itemHand,GetCtlValue(itemHand) ^1);
  450.                     theItem = 0;
  451.                     break;
  452.                 default:
  453.                     theItem = 0;
  454.                     break;
  455.             }
  456.         }
  457.         
  458.         DisposDialog(theDialog);
  459.     }
  460. }
  461.  
  462.  
  463. SetPrefButtons(DialogPtr theDialog,PrefsRecHdl thePrefs)
  464. {
  465.     /* uses fields in prefs data structure to set buttons in dialog */
  466.     int            itemType,dValue;
  467.     Handle        itemHand;
  468.     Rect        itemBox;
  469.     Str32        startVal;
  470.     
  471.     if (thePrefs != NIL && theDialog != NIL) {
  472.         dValue = (*thePrefs)->CPUSpeed;
  473.         switch(dValue) {
  474.             case MediumCPU:
  475.                 GetDItem(theDialog,PDMediumButton,&itemType,&itemHand,&itemBox);
  476.                 break;
  477.             case SlowCPU:
  478.                 GetDItem(theDialog,PDSlowButton,&itemType,&itemHand,&itemBox);
  479.                 break;
  480.             case FastCPU:
  481.             default:
  482.                 GetDItem(theDialog,PDFastButton,&itemType,&itemHand,&itemBox);
  483.                 break;
  484.         }
  485.         SetCtlValue(itemHand,1);
  486.         dValue = (*thePrefs)->NumberFormat;
  487.         switch(dValue) {
  488.             case Octal:
  489.                 GetDItem(theDialog,PDOctalButton,&itemType,&itemHand,&itemBox);
  490.                 break;
  491.             case Hexadecimal:
  492.                 GetDItem(theDialog,PDHexButton,&itemType,&itemHand,&itemBox);
  493.                 break;
  494.             case Decimal:
  495.             default:
  496.                 GetDItem(theDialog,PDDecimalButton,&itemType,&itemHand,&itemBox);
  497.                 break;
  498.         }
  499.         SetCtlValue(itemHand,1);
  500.         dValue = (*thePrefs)->DefaultStart;
  501.         NumToString(dValue,&startVal);
  502.         GetDItem(theDialog,PDVectorEditField,&itemType,&itemHand,&itemBox);
  503.         SetIText(itemHand,&startVal);
  504.     }
  505. }
  506.  
  507.  
  508. GetPrefButtons(DialogPtr theDialog,PrefsRecHdl thePrefs)
  509. {
  510.     /* uses buttons in dialog to set fields in prefs data structure */
  511.     
  512.     int        itemType,i;
  513.     Handle    itemHand;
  514.     Rect    itemBox;
  515.     Str32    startVal;
  516.     long    vector;
  517.     
  518.     if (thePrefs != NIL && theDialog != NIL) {
  519.         
  520.         for (i=PDFastButton;i<=PDSlowButton;i++) {
  521.             GetDItem(theDialog,i,&itemType,&itemHand,&itemBox);
  522.             if (GetCtlValue(itemHand))
  523.                 break;
  524.         }
  525.         switch(i) {
  526.             case PDMediumButton:
  527.                 (*thePrefs)->CPUSpeed = MediumCPU;
  528.                 break;
  529.             case PDSlowButton:
  530.                 (*thePrefs)->CPUSpeed = SlowCPU;
  531.                 break;
  532.             case PDFastButton:
  533.             default:
  534.                 (*thePrefs)->CPUSpeed = FastCPU;
  535.                 break;
  536.         }
  537.         for (i=PDDecimalButton;i<=PDBinaryButton;i++) {
  538.             GetDItem(theDialog,i,&itemType,&itemHand,&itemBox);
  539.             if (GetCtlValue(itemHand))
  540.                 break;
  541.         }
  542.         switch(i) {
  543.             case PDOctalButton:
  544.                 (*thePrefs)->NumberFormat = Octal;
  545.                 break;
  546.             case PDHexButton:
  547.                 (*thePrefs)->NumberFormat = Hexadecimal;
  548.                 break;
  549.             case PDDecimalButton:
  550.             default:
  551.                 (*thePrefs)->NumberFormat = Decimal;
  552.                 break;
  553.         }
  554.         GetDItem(theDialog,PDVectorEditField,&itemType,&itemHand,&itemBox);
  555.         GetIText(itemHand,&startVal);
  556.         StringToNum(&startVal,&vector);
  557.         (*thePrefs)->DefaultStart = LoWord(vector);
  558.     }
  559. }
  560.  
  561.  
  562. SetPrefDefaults(PrefsRecHdl thePrefs)
  563. {
  564.     /* sets the default preferences */
  565.     
  566.     if (thePrefs != NIL) {
  567.         (*thePrefs)->CPUSpeed = FastCPU;
  568.         (*thePrefs)->NumberFormat = Octal;
  569.         (*thePrefs)->DefaultStart = 0;
  570.         (*thePrefs)->cycleTime = TickCount();
  571.     }
  572. }
  573.  
  574.  
  575. char PDPProcHalted(WindowPtr pW)
  576. {
  577.     /* returns TRUE if processor halted, else FALSE */
  578.  
  579.     PDPRegHdl    theCPU;
  580.     
  581.     if (IsSimulator(pW)) {
  582.         theCPU = GetCPU(pW);
  583.         if (theCPU != NIL)
  584.             return((*theCPU)->CCR & HaltBit);
  585.     }
  586. }
  587.  
  588.  
  589. DisposeProcessWindow(WindowPtr theWindow)
  590. {
  591.     /* releases all storage related to a simulator window. */
  592.     ProcessRecHdl    theProcess;
  593.     PDPMemHdl        theMemory;
  594.     PDPRegHdl        theCPU;
  595.     int                aHit;
  596.     
  597.     if (IsSimulator(theWindow)) {
  598.         SetIndParamText(128,7);
  599.         aHit = xCautionAlert(GeneralAlertCancel,NIL);
  600.         if (aHit == ok) {
  601.             theProcess = GetProcess(theWindow);
  602.             theMemory = GetMemory(theWindow);
  603.             theCPU = GetCPU(theWindow);
  604.             if (theProcess != NIL)
  605.                 DisposHandle(theProcess);
  606.             if (theMemory != NIL)
  607.                 DisposHandle(theMemory);
  608.             if (theCPU != NIL)
  609.                 DisposHandle(theCPU);
  610.             DisposeWindow(theWindow);
  611.         }
  612.     }
  613. }
  614.             
  615.  
  616. StackWindows(void)
  617. {
  618.     /* call for stacking menu command, stacks Windows from top left to bottom right.
  619.         Current FrontWindow is topmost */
  620.         
  621.     WindowPeek    theWindow,listHead;
  622.     int            hGlob,vGlob,nWindows;
  623.     int            mWidth,mHeight;
  624.     GDHandle    theMonitor;
  625.     Rect        monRect;
  626.     short        optionWasDown;
  627.     
  628.     SetWatchCursor();
  629.     optionWasDown = OptionDown();
  630.     hGlob = 1;
  631.     vGlob = GetMBarHeight()+1;
  632.     listHead = (WindowPeek)FrontWindow();
  633.     nWindows = 0;
  634.     theWindow = listHead;
  635.     
  636.     if (IsInColour()) {
  637.         theMonitor = GetMainDevice();
  638.         monRect = (**theMonitor).gdRect;
  639.     }
  640.     else
  641.         monRect = screenBits.bounds;
  642.     
  643.     while (theWindow!=NIL) {
  644.         if (IsSimulator(theWindow) && theWindow->visible)
  645.             nWindows++;
  646.             
  647.         theWindow = theWindow->nextWindow;
  648.     }
  649.     
  650.     hGlob+=5*nWindows;
  651.     vGlob+=20*nWindows;
  652.     mWidth = monRect.right-monRect.left-hGlob-3;
  653.     if (mWidth < 200)
  654.         mWidth = 200;
  655.         
  656.     mHeight = monRect.bottom-monRect.top-vGlob-3;
  657.     if (mHeight < 100)
  658.         mHeight = 100;
  659.     
  660.     theWindow = listHead;
  661.     
  662.     while(theWindow!=NIL) {
  663.         if (IsSimulator(theWindow) && theWindow->visible) {
  664.             MoveWindow(theWindow,hGlob,vGlob,FALSE);
  665.             hGlob-=5;
  666.             vGlob-=20;
  667.         }
  668.         theWindow = theWindow->nextWindow;
  669.     }
  670. }
  671.         
  672.     
  673.  
  674.  
  675.  
  676.